package com.speedy.course.ext

import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.navigation.NavController
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.navOptions

data class NavigationPagerArgs(
    val key: String,
    val bundle: Bundle
)

/**
 * 用Navigation框架搭建Pager结构时，使用这些方法在Activity/Fragment中任何地方跳转到对应页面（singleTop模式）
 * 使用setFragmentResult API 传递数据
 */

fun FragmentActivity.navPager(id: Int, args: NavigationPagerArgs? = null) {
    findInstanceChild(NavHostFragment::class.java)?.apply {
        navController.navigate(id, null, navController.singleTopNavOptions())
        if (args != null) {
            childFragmentManager.setFragmentResult(args.key, args.bundle)
        }
    }
}

fun FragmentActivity.navPager(route: String, args: NavigationPagerArgs? = null) {
    findInstanceChild(NavHostFragment::class.java)?.apply {
        navController.navigate(route, navController.singleTopNavOptions())
        if (args != null) {
            childFragmentManager.setFragmentResult(args.key, args.bundle)
        }
    }
}

fun Fragment.navPager(id: Int, args: NavigationPagerArgs? = null) {
    findInstanceParent<NavHostFragment>()?.apply {
        navController.navigate(id, null, navController.singleTopNavOptions())
        if (args != null) {
            childFragmentManager.setFragmentResult(args.key, args.bundle)
        }
    }
}

fun Fragment.navPager(route: String, args: NavigationPagerArgs? = null) {
    findInstanceParent<NavHostFragment>()?.apply {
        navController.navigate(route, navController.singleTopNavOptions())
        if (args != null) {
            childFragmentManager.setFragmentResult(args.key, args.bundle)
        }
    }
}

fun NavController.singleTopNavOptions() = navOptions {
    launchSingleTop = true
    restoreState = true
    popUpTo(graph.findStartDestination().id) {
        inclusive = false
        saveState = true
    }
}



fun <T> FragmentActivity.findInstanceChild(clazz: Class<T>): T? {
    supportFragmentManager.fragments.forEach { fragment ->
        if (clazz.isInstance(fragment)) {
            return fragment as? T
        } else {
            fragment.findInstanceChild(clazz).also { find ->
                if (find != null) {
                    return find
                }
            }
        }
    }
    return null
}

fun <T> Fragment.findInstanceChild(clazz: Class<T>): T? {
    childFragmentManager.fragments.forEach { fragment ->
        if (clazz.isInstance(fragment)) {
            return fragment as? T
        } else {
            fragment.findInstanceChild(clazz).also { find ->
                if (find != null) {
                    return find
                }
            }
        }
    }
    return null
}

